import { HyperFormula } from "hyperformula";
import { arrayDeepLevel, nanoid10 } from "./Tools";
import HyperFormulaService from "../cpas-table/ExcelGrid/classes/HyperFormulaService";
//对齐方式枚举
const horizontal = {
    1: "left",
    2: "center",
    3: "right",
};
/**
 * handsonTable 转换excel style 参数说明
 *bl: number; // 是否加粗 1 不加粗 2 加粗
  r: number; // 缩进
  ht: number; // 对齐方式 1 左对齐 2居中对齐 3居右对齐
  bg: string; // 单元格背景颜色
  fc: string; // 字体颜色
  it: number; // 1 常规 、 2 斜体
  fs: number; // 字号 px

  bl: "bold",// 对应font： {bold：true/false }
  r: '',
  ht: 'text-', // alignment: { horizontal: "center" },
  bg: '', //  //fill: {bgColor: ''},
  fc: '', // font: {color: ''},
  it: '', //  font: {italic: true/false},
  fs: '', // font: {sz: 12 }

  {ht: 1, it: 2, fc: '#ff0000', bg: '#26ff00'}
 */
/**单元格样式转换 */
export function convertStyle(style, type) {
    let alignment = {
        horizontal: type === "numeric" ? "right" : "left",
        wrapText: true,
    }, fill = {
        fgColor: { rgb: "ffffff" },
    }, font = {
        sz: "12",
        name: type === "numeric" ? "Arial Narrow" : "仿宋_GB2312",
    };
    const defaultHt = type === "numeric" ? 3 : 1;
    const { bl = 1, r = "", ht = defaultHt, it, fc, bg } = style;
    font["bold"] = +bl === 2 ? true : false;
    font["italic"] = +it === 2 ? true : false;
    if (fc) {
        font["color"] = {
            rgb: fc.includes("#") ? fc.slice(1) : fc,
        };
    }
    if (bg) {
        let bgColor = bg.includes("#") ? bg.slice(1) : bg;
        if (bgColor.length === 3) {
            bgColor = `${bgColor}${bgColor}`;
        }
        fill["bgColor"] = {
            rgb: bgColor,
        };
        fill["fgColor"] = {
            rgb: bgColor,
        };
    }
    alignment["horizontal"] = horizontal[ht];
    return {
        alignment,
        fill,
        font,
    };
}
/**
 * 字符串按照固定位数切割
 * str: 数据
 */
function strToArray(str) {
    let result = [];
    for (let i = 0; i < str.length; i += 500) {
        result.push({
            v: str.slice(i, i + 500),
            t: "s",
        });
    }
    return result;
}
const borderStyle = {
    border: {
        top: { style: "thin", color: { rgb: "000000" } },
        bottom: { style: "thin", color: { rgb: "000000" } },
        left: { style: "thin", color: { rgb: "000000" } },
        right: { style: "thin", color: { rgb: "000000" } },
    },
};
function setTableHeaderStyle(obj) {
    const { exportType, headCellIndex } = obj;
    let headerStyle = {
        ...borderStyle.border,
    };
    /** header样式处理--begin */
    if (exportType === "primary") {
        if (headCellIndex === 1) {
            headerStyle = {
                top: { style: "thin", color: { rgb: "000000" } },
                bottom: { style: "thin", color: { rgb: "000000" } },
                left: { style: "none", color: { rgb: "000000" } },
                right: { style: "thin", color: { rgb: "000000" } },
            };
        }
        else {
            headerStyle = {
                top: { style: "thin", color: { rgb: "000000" } },
                bottom: { style: "thin", color: { rgb: "000000" } },
                left: { style: "thin", color: { rgb: "000000" } },
                right: { style: "none", color: { rgb: "000000" } },
            };
        }
    }
    /** header样式处理--end */
    return {
        headerStyle,
    };
}
function setTableStyle(obj) {
    const { exportType, bodyCellIndex, bodyRowIndex, rowLen } = obj;
    let bodyStyle = {
        ...borderStyle.border,
    };
    if (exportType === "primary") {
        if (bodyCellIndex < 2 && bodyRowIndex !== rowLen - 1) {
            //中间单元格没有边框线
            bodyStyle = {
                top: { style: "none", color: { rgb: "000000" } },
                bottom: { style: "none", color: { rgb: "000000" } },
                left: { style: "none", color: { rgb: "000000" } },
                right: { style: "none", color: { rgb: "000000" } },
            };
        }
        else if (bodyRowIndex === rowLen - 1) {
            //添加左边线和底部边线
            bodyStyle = {
                top: { style: "none", color: { rgb: "000000" } },
                bottom: { style: "thin", color: { rgb: "000000" } },
                left: {
                    style: bodyCellIndex === 1 ? "none" : "thin",
                    color: { rgb: "000000" },
                },
                right: { style: "none", color: { rgb: "000000" } },
            };
        }
        else {
            //默认只有右侧边框线
            bodyStyle = {
                top: { style: "none", color: { rgb: "000000" } },
                bottom: { style: "none", color: { rgb: "000000" } },
                left: { style: "thin", color: { rgb: "000000" } },
                right: { style: "none", color: { rgb: "000000" } },
            };
        }
    }
    /**table body样式--end */
    return {
        bodyStyle,
    };
}
/**
 * merge新老excel数据
 */
export function mergeTableData(oldTableCfg, newData, isShowTitle) {
    const oldHeaderData = oldTableCfg.header;
    const oldData = oldTableCfg.data || [];
    const isShowMaps = oldTableCfg.isShowMaps || false;
    const levelNum = arrayDeepLevel(oldHeaderData); //计算header深度
    let headerData = oldHeaderData.slice(0);
    let loadNewData = newData.slice(levelNum + 1);
    let headerNewData = newData.slice(0, 1);
    let titleArray = [];
    //导出时打开匹配行列关系，再次导入数据需要处理
    if (isShowMaps) {
        loadNewData = newData.slice(levelNum + 2);
    }
    //有标题的情况
    if (isShowTitle) {
        titleArray = newData.slice(0, 3);
        if (isShowMaps) {
            loadNewData = newData.slice(levelNum + 5);
        }
        else {
            loadNewData = newData.slice(levelNum + 4);
        }
        headerNewData = newData.slice(3, 4);
    }
    //处理复合表头数据兼容
    if (levelNum > 0 && headerNewData.length) {
        //行列关系关闭的情况下cpastable不展示，反之打开行列关系的主键展示
        if (!isShowMaps) {
            headerNewData[0].unshift("");
        }
    }
    //更新Data配置数据
    for (let i = 0; i < loadNewData.length; i++) {
        const oldCells = oldData[i] || [];
        const cells = loadNewData[i];
        //行列关系关闭的情况下隐藏主键
        if (!isShowMaps) {
            cells.unshift(i);
        }
        cells.push("");
        for (let j = 0; j < cells.length; j++) {
            if (i === 0 && oldCells[j]) {
                //cells[j] = oldCells[j];
            }
            if (j === cells.length - 1) {
                const rId = '{"rId":"' + nanoid10() + '"}';
                cells[j] = oldCells[j] ? oldCells[j] : rId;
            }
        }
    }
    //更新header数据
    for (let i = 0; i < oldHeaderData.length; i++) {
        if (i > 0 && i !== oldHeaderData.length - 1 && levelNum < 0) {
            //levelNum小于0,排除复合表头数据更新
            const labelName = headerNewData[0][i];
            if (!oldHeaderData[i].children && labelName) {
                headerData[i].label = labelName;
            }
        }
        //行列关系打开的情况下，header数据需要手动添加
        /*if(isShowMaps && i === 1) {
          headerData.splice(i, 0, {
            label: headerNewData[0][i],
            key: '{"rId":"' + nanoid10() + '-key"}' || "",
            config: {},
          })
        }*/
    }
    let titleData = {};
    // 兼容处理---打开工具栏匹配行列关系
    if (titleArray.length) {
        const descRow = titleArray[2];
        const titleRow = titleArray[0];
        const dateRow = titleArray[1];
        titleData = {
            tableTitle: titleRow[0] ? titleRow[0] : titleRow[1],
            tableLfDesc: descRow[0] ? descRow[0] : descRow[1],
            tableRiDesc: descRow[descRow.length - 1],
            tableDate: dateRow[0] ? dateRow[0] : dateRow[1],
            //tableDate,
        };
    }
    return {
        newData: loadNewData,
        headerNewData: headerData,
        titleData,
    };
}
//将table数据转换为excel格式
export function formatTabletoExcel({ self, headerDescDatas, exportType, isEditFormula, }) {
    let sourceData = self.hot.getSourceData();
    const gridData = self.hot.getData();
    const gridRef = self.gridRef ? self.gridRef : self;
    const isShowMaps = gridRef.isShowMaps;
    const { computerLevelData, headerColumn, lastHeader } = self.headerService.headerLevelData;
    const columnIndexMapper = self.hot.columnIndexMapper;
    const { descDatas = [], descMergeArray = [], imoportTableTitle = {}, signData = [], signMergeArray = [], } = headerDescDatas ? headerDescDatas : {};
    const isShowTableTitle = descDatas.length ? true : false;
    const saveObj = self.getCpasTableGrid
        ? self.getCpasTableGrid()
        : self.gridRef.getCpasTableGrid();
    //存储表格数据--导入时需要/
    const localTableData = JSON.stringify({
        /*header: [...headerData],
        data: [...gridData],
        cellsMeta: [...filterMetas],*/
        ...saveObj,
        isShowMaps,
        tableTitle: imoportTableTitle,
    });
    console.log(localTableData, "存储表格数据");
    let headerLength = computerLevelData.length;
    let excelData = [];
    let headerArray = [];
    let mergeArray = [...descMergeArray];
    const defaultBorder = {
        ...borderStyle.border,
    };
    //是否需要刷excel公式
    if (isEditFormula && isShowTableTitle) {
        sourceData = HyperFormulaService.transformExcelGridData(sourceData, 3, "row");
    }
    //打开匹配行列关系，多一列，title合并单元格需要多一列
    if (isShowMaps && descMergeArray.length) {
        for (let i = 0; i < descMergeArray.length; i++) {
            const row = descMergeArray[i];
            const { s, e } = row;
            row.s = {
                c: s.c + 1,
                r: s.r, //开始行
            };
            row.e = {
                c: e.c + 1,
                r: e.r, //结束行
            };
        }
        mergeArray = [...descMergeArray];
    }
    else {
        mergeArray = [...descMergeArray];
    }
    for (let i = 0; i < computerLevelData.length; i++) {
        const headerRow = computerLevelData[i];
        let excelHeaderRow = [];
        for (let j = 0; j < headerRow.length; j++) {
            const headerCell = headerRow[j];
            if (j === lastHeader) {
                continue;
            }
            //行列关系开关关闭隐藏主键
            if (columnIndexMapper.isHidden(j)) {
                continue;
            }
            if (!headerCell) {
                excelHeaderRow.push({
                    v: "",
                    s: {
                        border: {
                            ...defaultBorder,
                        },
                    },
                });
                continue;
            }
            const { colspan, rowspan, label, config } = headerCell;
            let cellVertical = "center";
            if (config && +config?.ht === 1) {
                cellVertical = "left";
            }
            if (config && +config?.ht === 3) {
                cellVertical = "right";
            }
            /**header样式处理 --begin */
            if (headerCell.label !== "rowConfig") {
                /*单独提取公共部门进行开发begin*/
                const { headerStyle } = setTableHeaderStyle({
                    exportType,
                    headCellIndex: j,
                });
                /*单独提取公共部门进行开发end*/
                excelHeaderRow.push({
                    v: headerCell.label === "null" ? "" : headerCell.label,
                    s: {
                        alignment: {
                            vertical: "center",
                            horizontal: cellVertical,
                        },
                        //fill: { fgColor: { rgb: "eeeeee" }, patternType: "solid" },
                        font: {
                            sz: "12",
                            name: "仿宋_GB2312",
                            bold: config && +config?.bl === 2 ? true : false,
                        },
                        border: {
                            ...headerStyle,
                        },
                    },
                    t: "s",
                });
                // 1.1 行总数rowspan = 最深level
                // 1.2 列总数colspan = 所有可操作表头字段的总数（叶子节点总数）
                // 1.3 level = 最深的叶子几点层级/此处没有用到
                const isMergeCell = (rowspan > 1 || colspan > 1) && label && label !== "null"; //label非空校验&&排除表头的空白行
                if (isMergeCell) {
                    const defaultStartRow = descDatas && descDatas.length ? 3 : 0; //有标题的情况下，行从第三行开始计算
                    const sR = i + defaultStartRow;
                    const eR = i + (rowspan - 1 + defaultStartRow);
                    let sC = j - 1;
                    let eC = j + (colspan - 2);
                    //处理打开行列匹配
                    if (isShowMaps) {
                        sC = j;
                        eC = j + (colspan - 1);
                    }
                    mergeArray.push({
                        s: { c: sC, r: sR },
                        e: { c: eC, r: eR }, // 合并结束位置 c:列位置 r:表示行位置
                    });
                }
            }
            /**headerr样式处理 ---end */
        }
        headerArray.push(excelHeaderRow);
    }
    //由于表头在excel中是占用行号的，这里做一个刷新
    const hfInstance = HyperFormula.buildFromArray(sourceData);
    hfInstance.addSheet("excelTmp");
    hfInstance.addRows(0, [0, computerLevelData.length]);
    const tmpExcelData = hfInstance.getSheetSerialized(0);
    tmpExcelData.splice(0, computerLevelData.length);
    for (let i = 0; i < tmpExcelData.length; i++) {
        const sourceRow = tmpExcelData[i];
        let excelRow = [];
        if (i < computerLevelData.length && columnIndexMapper.isHidden(i)) {
            continue;
        }
        for (let j = 0; j < sourceRow.length; j++) {
            //行列关系关闭需要隐藏主键
            if (columnIndexMapper.isHidden(j)) {
                continue;
            }
            const excelCell = {};
            const f_v = sourceRow[j]; // 公式值
            const d_v = gridData[i][j]; // 显示值
            const config = headerColumn[j]?.config ? headerColumn[j]?.config : {};
            const { type, custom = {}, groupHeader } = self.hot.getCellMeta(i, j);
            const { r = 0 } = custom;
            const { alignment, fill, font } = convertStyle(custom, type);
            //excelCell["v"] = d_v;
            excelCell["v"] =
                custom && custom["r"] ? "　".repeat(custom["r"] * 1) + d_v : d_v;
            const reg = /(FS_CELL|CP_CELL|IN_CELL)/gi;
            if (f_v && !reg.test(f_v) && d_v !== f_v) {
                excelCell["f"] = f_v;
            }
            if (d_v === "" || d_v === null || +d_v === 0) {
                excelCell["v"] = "";
            }
            excelCell["t"] = type === "numeric" ? "n" : "s";
            const val = excelCell["v"];
            /*if (!isNaN(val)) {
              excelCell["v"] = formatPrice(val);
            }*/
            if (r) {
                excelCell["val"] = val.replaceAll("(.{1})", "$ ");
            }
            let style = {
                alignment: {
                    ...alignment,
                    vertical: "center",
                    wrapText: type === "text" ? true : false,
                    //indent: r,
                },
                font: {
                    ...font,
                },
                fill: {
                    ...fill,
                },
                border: {
                    ...defaultBorder,
                },
            };
            if (type === "numeric") {
                style["numFmt"] = "#,##0.00";
            }
            const groupStyle = {
                fill: { fgColor: { rgb: "117aaf" }, patternType: "solid", ...fill },
                font: {
                    color: { rgb: "ffffff" },
                    ...font,
                },
                alignment: {
                    ...alignment,
                },
            };
            if (groupHeader) {
                style = { ...style, ...groupStyle };
            }
            const { bodyStyle } = setTableStyle({
                exportType,
                bodyCellIndex: j,
                bodyRowIndex: i,
                rowLen: tmpExcelData.length,
            });
            excelCell["s"] = {
                ...style,
                border: {
                    ...bodyStyle,
                },
            };
            if (type === "numeric" &&
                config?.numericFormat?.pattern &&
                config?.numericFormat?.pattern === "0.00%") {
                excelCell["z"] = "0.00%";
            }
            excelRow.push(excelCell);
        }
        excelData.push(excelRow);
    }
    //表头行高
    let excel_rows = [];
    const headerRowsHeight = 30;
    for (let i = 0; i < headerLength; i++) {
        excel_rows.push({
            hpx: headerRowsHeight,
        });
    }
    //打开行列关系的情况下，隐藏表格内容主键
    if (isShowMaps) {
        for (let i = 0; i < tmpExcelData.length + 5; i++) {
            if (!descDatas.length) {
                excel_rows.push({
                    hidden: i == 0 ? true : false,
                });
            }
            else {
                excel_rows.push({
                    hidden: i == 3 ? true : false,
                });
            }
        }
    }
    let excel_columns = [];
    let dfColumnWidth = 150;
    //列宽
    for (let i = 0; i < headerColumn.length; i++) {
        const headerItem = headerColumn[i];
        excel_columns.push({
            hidden: isShowMaps && i === 0 ? true : false,
            wpx: headerItem.config && headerItem.config.width
                ? headerItem.config.width
                : dfColumnWidth,
        });
    }
    console.log("导入到excel中的数据");
    console.log([...headerArray, ...excelData]);
    const datas = [];
    if (descDatas && descDatas.length && !isShowMaps) {
        datas.push(...descDatas);
    }
    //打开行列关系匹配，标题的合并需要单独处理
    if (descDatas && descDatas.length && isShowMaps) {
        for (let i = 0; i < descDatas.length; i++) {
            const row = descDatas[i];
            row.unshift({
                v: "",
                s: {},
            });
        }
        datas.push(...descDatas);
    }
    datas.push(...headerArray, ...excelData);
    //处理签字行
    if (signData && !isShowMaps) {
        datas.push([{}]);
        datas.push(signData);
    }
    if (signData && signData.length && isShowMaps) {
        signData.unshift({
            v: "",
            s: {},
        });
        datas.push([{}]);
        datas.push(signData);
    }
    console.log(datas, "datas----signData", signData);
    let rows = strToArray(localTableData);
    let excel_columns_tablecfg = [];
    for (let i = 0; i < rows.length; i++) {
        excel_columns_tablecfg.push({
            hidden: true,
        });
    }
    if (isShowMaps && signMergeArray.length) {
        for (let i = 0; i < signMergeArray.length; i++) {
            const row = signMergeArray[i];
            const { s, e } = row;
            row.s = {
                c: s.c + 1,
                r: s.r, //开始行
            };
            row.e = {
                c: e.c + 1,
                r: e.r, //结束行
            };
        }
        console.log(signMergeArray, "signMergeArray----");
        mergeArray.push(...signMergeArray);
    }
    else if (signMergeArray.length) {
        mergeArray.push(...signMergeArray);
    }
    console.log(mergeArray, "mergeArray---");
    return {
        datas,
        excelData,
        mergeArray,
        excel_columns,
        excel_rows,
        excel_columns_tablecfg,
        localTableData,
        rows,
    };
}
